﻿using System;
using Hr.Interfaces;
using Hr.Models;
using Hr.Models.Common;

namespace Hr.Business
{
    public class MainImpl : IMain
    {
        /// <summary>
        /// 员工工资结算
        /// </summary>
        /// <param name="employeeId">员工ID</param>
        /// <param name="endDate">结算日期</param>
        public void CalcSalary(string employeeId, DateTime endDate)
        {
            // 1、获取员工的工资标准
            var salaryStandard = new SalaryStandard(); // 只支持一个月一个标准的
            // 2、获取员工的考勤数据
            var workTime = new EmployeeWorkTime();
            CalcSalary(workTime, salaryStandard);
        }

        /// <summary>
        /// 员工工资结算
        /// </summary>
        /// <param name="workTime">实际上班状况</param>
        /// <param name="salaryStandard">工资标准</param>
        public void CalcSalary(EmployeeWorkTime workTime, SalaryStandard salaryStandard)
        {
            workTime.FullWorkHours = GetFullWorkHours(workTime.HappenMonth);
            // 基本工资
            workTime.Result.BaseSalary = salaryStandard.Total * (workTime.WorkHours + workTime.PaidHolidayHours) / workTime.FullWorkHours;
            // 加班工资
            CalcExtraSalary(workTime, salaryStandard);
            // 绩效
            workTime.Result.MeritPay = salaryStandard.MeritPay + salaryStandard.Others;
            // 计算应扣
            CalcYinKou(salaryStandard, workTime);
        }

        /// <summary>
        /// 计算加班费
        /// </summary>
        private void CalcExtraSalary(EmployeeWorkTime workTime, SalaryStandard salaryStandard)
        {
            var sum = workTime.ChPsjbHours * salaryStandard.SalaryPerHours * 1.5;
            sum += workTime.ChZmjbHours * salaryStandard.SalaryPerHours * 2;
            sum += workTime.ChJrjbHours * salaryStandard.SalaryPerHours * 3;
            workTime.Result.ExtraSalary = Math.Round(sum, 2);
        }

        /// <summary>
        /// 计算应扣金额
        /// </summary>
        /// <param name="salaryStandard"></param>
        /// <param name="workTime"></param>
        private void CalcYinKou(SalaryStandard salaryStandard, EmployeeWorkTime workTime)
        {
            // 旷工，扣（满勤+绩效+三倍工资）
            if (workTime.ChKuangongHours > 0)
            {
                workTime.Result.DeFullWork = salaryStandard.Base.FullWork;
                workTime.Result.DeMeritPay = salaryStandard.MeritPay;
                workTime.Result.DeOthers = workTime.ChKuangongHours * salaryStandard.SalaryPerHours * 3;
            }
            else
            {
                // 扣满勤
                workTime.Result.DeFullWork = KouMangQing(salaryStandard, workTime);

                // 扣绩效奖金
                if (salaryStandard.MeritPayType == 1)
                {
                    double hours = workTime.WorkHours + workTime.PaidHolidayHours;
                    workTime.Result.MeritPay = Math.Round(salaryStandard.MeritPay*hours/workTime.FullWorkHours, 2);
                    workTime.Result.DeMeritPay = salaryStandard.MeritPay - workTime.Result.MeritPay;
                }
                else
                {
                    workTime.Result.MeritPay = Math.Round(salaryStandard.MeritPay * (1 - workTime.PercentOfMeritPay),2);
                }
            }
        }

        /// <summary>
        /// 扣满勤
        /// </summary>
        /// <param name="salaryStandard"></param>
        /// <param name="workTime"></param>
        /// <returns>应扣满勤总金额</returns>
        private double KouMangQing(SalaryStandard salaryStandard, EmployeeWorkTime workTime)
        {
            // 实际出勤不足15天，全扣
            if (workTime.WorkHours < 15 * 8) return salaryStandard.Base.FullWork;

            // 事假扣满勤
            double sum = salaryStandard.Base.FullWork * QingShiJia(workTime.ChShiJiaHours);

            return Math.Round(sum, 2);
        }

        /// <summary>
        /// 获取指定月份的满勤工作时间（小时）
        /// </summary>
        /// <param name="happenMonth">某个月</param>
        /// <returns></returns>
        private double GetFullWorkHours(DateTime happenMonth)
        {
            return 21.75 * 8;
        }

        /// <summary>
        /// 请事假，半天扣1/4满勤
        /// </summary>
        /// <param name="hours">事假小时数</param>
        /// <returns></returns>
        private double QingShiJia(double hours)
        {
            if (hours <= 0)
                return 0;
            if (hours > 0 && hours <= 4)
                return 0.25;
            if (hours > 4 && hours <= 8)
                return 0.5;
            if (hours > 8 && hours <= 12)
                return 0.75;
            return 1.0;
        }
    }
}
